#include "SchedulerInc.h"

using namespace bimar_scheduler_lib;

class CSleepTask : public CTask
{
public:
  CSleepTask(gulong id, gulong iterations = 100)
  :m_id(id), m_iterations(iterations)
  {
    g_print("CSleepTask(%d)::CSleepTask\n", m_id);
  }
  virtual ~CSleepTask()
  {
    g_print("CSleepTask(%d)::~CSleepTask\n", m_id);
  }

protected:
  gboolean Run()
  {
    CTask::Run();

    g_print("CSleepTask(%d)::Run start\n", m_id);

	gchar * progress[] = {"/\r", "-\r", "\\\r", "|\r", "/\r", "-\r", "\\\r", "|\r"};
	for(gulong i=0; i<m_iterations && (m_status!=EStatus_Aborted);)
	{
	  switch(m_status)
	  {
	    case EStatus_Running:
	    {
	      g_print("(%02d)(%03d)%s", m_id, i, progress[i%8]);
	      g_usleep(G_USEC_PER_SEC/10);
	      i++;
		}
		break;
		case EStatus_Paused:
		break;
		case EStatus_Stopped:
		  i = 0;
	    break;
	  }	  
	}
	g_print("\nCSleepTask(%d)::Run end\n", m_id);

    return TRUE;
  }

protected:
  gulong m_id;
  gulong m_iterations;
};

static void TestScheduler1()
{
  CSleepTask *task0 = new CSleepTask(0, 100);
  CSleepTask *task1 = new CSleepTask(1, 200);
  CSleepTask *task2 = new CSleepTask(2, 300);
  // CSleepTask *task3 = new CSleepTask(3, 50);
  task1->SetPropertyPrevParallel();

  CJob job1;
  job1.PushBack(task0);
  job1.PushBack(task1);
  job1.PushBack(task2);
  // job1.PushBack(task3);

  // CSleepTask *task4 = new CSleepTask(4, 50);
  // CSleepTask *task5 = new CSleepTask(5, 100);
  // CSleepTask *task6 = new CSleepTask(6, 150);
  // CSleepTask *task7 = new CSleepTask(7, 200);
  // task5->SetPropertyPrevParallel();

  // CJob job2;
  // job2.PushBack(task4);
  // job2.PushBack(task5);
  // job2.PushBack(task6);
  // job2.PushBack(task7);

  // job2.SetPropertyPrevParallel();

  // CJob job;
  // job.PushBack(job1);
  // job.PushBack(job2);
  
  CJobExecutor executor;
  // executor.StartJob(&job);
  executor.StartJob(&job1);
  g_usleep(G_USEC_PER_SEC);
  g_print("PAUSE!!!!\n");
  executor.PauseCurrentJob();
  g_usleep(G_USEC_PER_SEC);
  g_print("STOP!!!!\n");
  executor.StopCurrentJob();
  g_print("RESUME!!!!\n");
  executor.ResumeCurrentJob();
  g_usleep(G_USEC_PER_SEC);
  g_print("ABORT!!!!\n");
  executor.AbortCurrentJob();
  while(!executor.IsIdle())
    g_thread_yield();
}

void AddTestScheduler()
{
  g_test_add_func("/scheduler/scheduler1", TestScheduler1);
}